from uuid import UUID
from typing import List
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException, BackgroundTasks, Body
from fastapi.responses import FileResponse
from sqlalchemy.ext.asyncio import AsyncSession
import os

from core import attachment as attachment_service
from schemas.attachment import AttachmentResponse
from db.session import get_db
from log import log_api, log_error

router = APIRouter(
    prefix="/attachments",
    tags=["attachments"]
)

@router.post("/{compliance_item_id}", response_model=AttachmentResponse)
async def upload_attachment(
    compliance_item_id: UUID,
    file: UploadFile = File(...),
    db: AsyncSession = Depends(get_db)
) -> AttachmentResponse:
    """
    上传附件
    
    - **compliance_item_id**: 合规项ID
    - **file**: 上传的文件
    """
    log_api(f"Uploading attachment for compliance item ID: {compliance_item_id}", module="router.attachment")
    return await attachment_service.save_attachment(db, file, compliance_item_id)

@router.get("/{attachment_id}")
async def get_attachment_file(
    attachment_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    获取单个附件的文件内容
    
    - **attachment_id**: 附件ID
    
    返回:
        文件内容的二进制流
    """
    log_api(f"Getting attachment file with ID: {attachment_id}", module="router.attachment")
    try:
        # 获取附件信息
        attachment = await attachment_service.get_attachment(db, attachment_id)
        if not attachment:
            raise HTTPException(status_code=404, detail="Attachment not found")
        
        # 检查文件是否存在
        if not os.path.exists(attachment.path):
            log_error(f"Attachment file not found at path: {attachment.path}")
            raise HTTPException(status_code=404, detail="Attachment file not found")
            
        return FileResponse(
            path=attachment.path,
            filename=attachment.name,
            media_type=attachment.type
        )
        
    except Exception as e:
        log_error(f"Error retrieving attachment file: {str(e)}")
        if isinstance(e, HTTPException):
            raise
        raise HTTPException(status_code=500, detail="Error retrieving attachment file")

@router.delete("/{attachment_id}")
async def delete_attachment(
    attachment_id: UUID,
    db: AsyncSession = Depends(get_db)
) -> dict:
    """
    删除附件
    
    - **attachment_id**: 附件ID
    """
    log_api(f"Deleting attachment with ID: {attachment_id}", module="router.attachment")
    result = await attachment_service.delete_attachment_with_file(db, attachment_id)
    if not result:
        raise HTTPException(status_code=404, detail="Attachment not found")
    return {"message": "Attachment deleted successfully"}

@router.get("/assessment-plan/{assessment_plan_id}", response_model=List[AttachmentResponse])
async def get_attachments_by_assessment_plan(
    assessment_plan_id: UUID,
    db: AsyncSession = Depends(get_db)
) -> List[AttachmentResponse]:
    """
    根据评估计划ID查询所有附件
    
    - **assessment_plan_id**: 评估计划ID
    
    返回:
        附件列表
    """
    log_api(f"Getting attachments for assessment plan ID: {assessment_plan_id}", module="router.attachment")
    return await attachment_service.get_attachments_by_assessment_plan(db, assessment_plan_id)


@router.post("/copy/{compliance_item_id}", response_model=List[AttachmentResponse])
async def copy_existing_attachments(
    compliance_item_id: UUID,
    attachment_ids: List[UUID] = Body(..., embed=True),
    db: AsyncSession = Depends(get_db)
) -> List[AttachmentResponse]:
    """
    复制已有的附件到检查项（创建新的文件和记录）
    
    - **compliance_item_id**: 检查项ID
    - **attachment_ids**: 要复制的附件ID列表
    
    返回:
        新创建的附件记录列表
    """
    log_api(f"Copying {len(attachment_ids)} attachments to compliance item ID: {compliance_item_id}", module="router.attachment")
    return await attachment_service.copy_existing_attachments(db, compliance_item_id, attachment_ids)


@router.get("/export/{assessment_plan_id}")
async def export_assessment_plan_attachments(
    assessment_plan_id: UUID,
    background_tasks: BackgroundTasks,
    db: AsyncSession = Depends(get_db)
):
    """
    导出评估计划的所有附件为压缩包
    
    - **assessment_plan_id**: 评估计划ID
    
    返回:
        压缩包文件下载
    """
    log_api(f"Exporting attachments for assessment plan ID: {assessment_plan_id}", module="router.attachment")
    
    zip_path = None
    try:
        # 创建压缩包
        zip_path = await attachment_service.export_assessment_plan_attachments(db, assessment_plan_id)
        
        # 添加后台任务删除临时文件（仅在成功时）
        background_tasks.add_task(os.remove, zip_path)
        
        return FileResponse(
            path=zip_path,
            filename=os.path.basename(zip_path),
            media_type='application/zip'
        )
        
    except Exception as e:
        # 如果出错且压缩包已创建，立即删除
        if zip_path and os.path.exists(zip_path):
            try:
                os.remove(zip_path)
                log_api(f"Cleaned up failed export file: {zip_path}", module="router.attachment")
            except Exception as cleanup_error:
                log_error(f"Failed to cleanup export file {zip_path}: {str(cleanup_error)}", module="router.attachment")
        
        log_error(f"Error exporting attachments: {str(e)}")
        if isinstance(e, HTTPException):
            raise
        raise HTTPException(status_code=500, detail="导出附件失败") 